import * as Cesium from 'cesium'
import * as turf from '@turf/turf'

// 定义是否开启测量距离功能
let ismeasurePolyline = true
// 定义测量距离数据列表
let measurePolylineList = [[]]
// 定义距离测量的输入事件
let measurePolylineEventHander = null

/** 测量距离
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 */
export const measurePolyline = (viewer) => {
  if (ismeasurePolyline) {
    // 防止二次定义
    ismeasurePolyline = false

    // 定义距离测量的输入事件
    measurePolylineEventHander = new Cesium.ScreenSpaceEventHandler(
      viewer.scene.canvas
    )
    // 定义点击点的集合
    let clickPoint = []
    let verdictPoint = []

    // 添加鼠标左键点击功能 —— 测量距离
    measurePolylineEventHander.setInputAction((movement) => {
      const ellipsoid = viewer.scene.globe.ellipsoid
      //当前世界坐标笛卡尔积
      const verdictPosition = viewer.camera.pickEllipsoid(
        movement.position, //像素的x和y坐标
        ellipsoid // 要选取的椭球体
      )

      const earthPosition = viewer.scene.pickPosition(movement.position)
      if (Cesium.defined(earthPosition)) {
        // 判断现在是第几个点
        if (clickPoint.length === 0) {
          //还没有点，添加第一个点
          verdictPoint.push(verdictPosition)
          clickPoint.push(earthPosition)

          // 将点实体添加到集合中
          const pointEntity = viewer.entities.add({
            name: 'measurePoint',
            position: earthPosition,
            point: {
              pixelSize: 5, //点的大小
              color: Cesium.Color.WHITE, //点的颜色
              outlineColor: Cesium.Color.fromCssColorString(
                'rgba(49,120,252,0.8)'
              ), //外圈颜色
              outlineWidth: 2, //外圈大小
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
            },
          })

          // 存储到矩形列表中
          const pointObj = {
            name: 'measurePoint',
            entity: pointEntity,
          }
          measurePolylineList[measurePolylineList.length - 1].push(pointObj)
        } else {
          if (
            JSON.stringify(verdictPosition) !==
            JSON.stringify(verdictPoint[verdictPoint.length - 1])
          ) {
            verdictPoint.push(verdictPosition)
            clickPoint.push(earthPosition)
            removePolylineEntityByName(viewer, 'moveMeasurePolyline')

            // 定义绘制最后一段的多边线
            const polylineItem = [
              clickPoint[clickPoint.length - 2],
              clickPoint[clickPoint.length - 1],
            ]
            // 定义中间点
            const Cartesian3_x = (polylineItem[0].x + polylineItem[1].x) / 2
            const Cartesian3_y = (polylineItem[0].y + polylineItem[1].y) / 2
            const Cartesian3_z = (polylineItem[0].z + polylineItem[1].z) / 2
            const centerPoint = new Cesium.Cartesian3(
              Cartesian3_x,
              Cartesian3_y,
              Cartesian3_z
            )

            // 计算两点的距离
            const polylineItemDistance = calculatedDistance(polylineItem)

            // 将实体添加到集合中
            const polylineEntity = viewer.entities.add({
              name: 'measurePolyline',
              polyline: {
                positions: polylineItem,
                material: Cesium.Color.fromCssColorString(
                  'rgba(49,120,252,0.8)'
                ),
                depthFailMaterial: Cesium.Color.fromCssColorString(
                  'rgba(49,120,252,0.8)'
                ),
                width: 2.0,
                clampToGround: false,
              },
            })

            // 存储到矩形列表中
            const polylineObj = {
              name: 'measurePolyline',
              entity: polylineEntity,
            }
            measurePolylineList[measurePolylineList.length - 1].push(
              polylineObj
            )

            // 将文字实体添加到集合中
            const labelEntity = viewer.entities.add({
              name: 'measureLabel',
              position: centerPoint,
              label: {
                text: `距离:${
                  polylineItemDistance.toFixed(2) > 1000
                    ? (polylineItemDistance / 1000).toFixed(2) + 'KM'
                    : polylineItemDistance.toFixed(2) + 'M'
                }`,
                font: '14px sans-serif',
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                fillColor: Cesium.Color.WHITE,
                outlineColor: Cesium.Color.WHITE,
                showBackground: true, //指定标签后面背景的可见性
                backgroundColor:
                  Cesium.Color.fromCssColorString('rgba(0,0,0,0.6)'), // 背景颜色
                backgroundPadding: new Cesium.Cartesian2(6, 6), //指定以像素为单位的水平和垂直背景填充padding
                scaleByDistance: new Cesium.NearFarScalar(2000, 1, 80000, 0.5),
                distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                  0,
                  80000
                ),
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
              },
            })

            // 存储到矩形列表中
            const labelObj = {
              name: 'measureLabel',
              entity: labelEntity,
            }
            measurePolylineList[measurePolylineList.length - 1].push(labelObj)

            // 将点实体添加到集合中
            const pointEntity = viewer.entities.add({
              name: 'measurePoint',
              position: earthPosition,
              point: {
                pixelSize: 5, //点的大小
                color: Cesium.Color.WHITE, //点的颜色
                outlineColor: Cesium.Color.fromCssColorString(
                  'rgba(49,120,252,0.8)'
                ), //外圈颜色
                outlineWidth: 2, //外圈大小
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
              },
            })

            // 存储到矩形列表中
            const pointObj = {
              name: 'measurePoint',
              entity: pointEntity,
            }
            measurePolylineList[measurePolylineList.length - 1].push(pointObj)
          }
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

    // 添加鼠标移动功能 —— 鼠标移动过程中查看线
    measurePolylineEventHander.setInputAction((movement) => {
      const newPosition = viewer.scene.pickPosition(movement.endPosition)

      if (Cesium.defined(newPosition)) {
        if (clickPoint.length > 0) {
          const movePoint = [clickPoint[clickPoint.length - 1], newPosition]

          removePolylineEntityByName(viewer, 'moveMeasurePolyline')
          // 将实体添加到集合中
          const movePolylineEntity = viewer.entities.add({
            name: 'moveMeasurePolyline',
            polyline: {
              positions: new Cesium.CallbackProperty(function () {
                return movePoint
              }, false),
              material: new Cesium.PolylineDashMaterialProperty({
                color: Cesium.Color.fromCssColorString('rgba(49,120,252,0.8)'),
                dashLength: 10, //短划线长度
              }),
              width: 2.0,
              clampToGround: true,
            },
          })

          // 存储到矩形列表中
          const polylineObj = {
            name: 'moveMeasurePolyline',
            entity: movePolylineEntity,
          }
          measurePolylineList[measurePolylineList.length - 1].push(polylineObj)
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)

    // 添加鼠标右键点击功能 —— 撤销测量距离上一步骤
    measurePolylineEventHander.setInputAction(() => {
      removePolylineEntityByName(viewer, 'moveMeasurePolyline')
      clickPoint.pop()
      verdictPoint.pop()
      const subListLength =
        measurePolylineList[measurePolylineList.length - 1].length

      if (subListLength === 1) {
        const isRemove = viewer.entities.remove(
          measurePolylineList[measurePolylineList.length - 1][subListLength - 1]
            .entity
        )
        if (isRemove) {
          // 数组中移除数据
          measurePolylineList[measurePolylineList.length - 1].pop()
        }
      } else if (subListLength > 1) {
        for (let i = 1; i < 4; i++) {
          const isRemove = viewer.entities.remove(
            measurePolylineList[measurePolylineList.length - 1][
              subListLength - i
            ].entity
          )
          if (isRemove) {
            // 数组中移除数据
            measurePolylineList[measurePolylineList.length - 1].pop()
          }
        }
      }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)

    // 添加鼠标双击左键点击功能 —— 绘制完成测量距离
    measurePolylineEventHander.setInputAction(() => {
      if (clickPoint.length > 0) {
        const totalPolylineDistance = calculatedTotalDistance(clickPoint)

        // 将文字实体添加到集合中
        const labelEntity = viewer.entities.add({
          name: 'measureLabel',
          position: clickPoint[clickPoint.length - 1],
          label: {
            text: `总距离:${
              totalPolylineDistance.toFixed(2) > 1000
                ? (totalPolylineDistance / 1000).toFixed(2) + 'KM'
                : totalPolylineDistance.toFixed(2) + 'M'
            }`,
            font: '14px sans-serif',
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            fillColor: Cesium.Color.WHITE,
            outlineColor: Cesium.Color.WHITE,
            showBackground: true, //指定标签后面背景的可见性
            backgroundColor: Cesium.Color.fromCssColorString('rgba(0,0,0,0.6)'), // 背景颜色
            backgroundPadding: new Cesium.Cartesian2(6, 6), //指定以像素为单位的水平和垂直背景填充padding
            scaleByDistance: new Cesium.NearFarScalar(2000, 1, 80000, 0.5),
            pixelOffset: new Cesium.Cartesian2(0, -25),
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
              0,
              80000
            ),
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          },
        })

        // 存储到矩形列表中
        const labelObj = {
          name: 'measureLabel',
          entity: labelEntity,
        }
        measurePolylineList[measurePolylineList.length - 1].push(labelObj)

        clickPoint = [] // 清空
        verdictPoint = [] // 清空
        measurePolylineList.push([])
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
  }
}

/** 移除测量距离Entity
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 * @param {string} entityName 移除的entity名称
 */
const removePolylineEntityByName = (viewer, entityName) => {
  // 获取移除数据在 entitieList中的位置
  const objItem = measurePolylineList[measurePolylineList.length - 1].find(
    (item) => item.name === entityName
  )
  const objIndex =
    measurePolylineList[measurePolylineList.length - 1].indexOf(objItem)

  // 移除图层数据
  if (objItem) {
    const isRemove = viewer.entities.remove(objItem.entity)
    if (isRemove) {
      // 数组中移除数据
      measurePolylineList[measurePolylineList.length - 1].splice(objIndex, 1)
    }
  }
}

/** 计算两点距离
 * @param {Array<Cartesian3>} Cartesian3Ponit
 */
const calculatedDistance = (Cartesian3Ponit) => {
  const distance = Cesium.Cartesian3.distance(
    Cartesian3Ponit[0],
    Cartesian3Ponit[1]
  )
  return distance
}

/** 计算全部距离
 * @param {Array<Cartesian3>} Cartesian3Ponit
 */
const calculatedTotalDistance = (Cartesian3Ponit) => {
  let totalDistance = 0

  for (let i = 1; i < Cartesian3Ponit.length; i++) {
    const distance = Cesium.Cartesian3.distance(
      Cartesian3Ponit[i - 1],
      Cartesian3Ponit[i]
    )
    totalDistance += Number(distance.toFixed(2))
  }

  return totalDistance
}

// 定义是否开启测量面积功能
let ismeasurePolygon = true
// 定义测量面积数据列表
let measurePolygonList = [[]]
// 定义面积测量的输入事件
let measurePolygonEventHander = null

/** 测量面积
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 */
export const measurePolygon = (viewer) => {
  if (ismeasurePolygon) {
    // 防止二次定义
    ismeasurePolygon = false

    // 定义面积测量的输入事件
    measurePolygonEventHander = new Cesium.ScreenSpaceEventHandler(
      viewer.scene.canvas
    )
    // 定义点击点的集合
    let clickPoint = []
    let verdictPoint = []

    // 添加鼠标左键点击功能 —— 测量面积
    measurePolygonEventHander.setInputAction((movement) => {
      const ellipsoid = viewer.scene.globe.ellipsoid
      //当前世界坐标笛卡尔积
      const verdictPosition = viewer.camera.pickEllipsoid(
        movement.position, //像素的x和y坐标
        ellipsoid // 要选取的椭球体
      )

      const earthPosition = viewer.scene.pickPosition(movement.position)
      if (Cesium.defined(earthPosition)) {
        // 判断现在是第几个点
        if (clickPoint.length === 0) {
          //还没有点，添加第一个点
          verdictPoint.push(verdictPosition)
          clickPoint.push(earthPosition)

          // 将点实体添加到集合中
          const pointEntity = viewer.entities.add({
            name: 'measurePoint',
            position: earthPosition,
            point: {
              pixelSize: 5, //点的大小
              color: Cesium.Color.WHITE, //点的颜色
              outlineColor: Cesium.Color.fromCssColorString(
                'rgba(49,120,252,0.8)'
              ), //外圈颜色
              outlineWidth: 2, //外圈大小
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
            },
          })

          // 存储到矩形列表中
          const pointObj = {
            name: 'measurePoint',
            entity: pointEntity,
          }
          measurePolygonList[measurePolygonList.length - 1].push(pointObj)
        } else {
          if (
            JSON.stringify(verdictPosition) !==
            JSON.stringify(verdictPoint[verdictPoint.length - 1])
          ) {
            verdictPoint.push(verdictPosition)
            clickPoint.push(earthPosition)

            // 删除移动绘制的矩形
            if (clickPoint.length > 2) {
              removePolygonEntityByName(viewer, 'moveMeasurePolygon')

              // 移除上一次的measurePolygon
              removePolygonEntityByName(viewer, 'measurePolygon')
              const polygonHierarchy = new Cesium.PolygonHierarchy(clickPoint)
              // 将实体添加到集合中
              const polygonEntity = viewer.entities.add({
                name: 'measurePolygon',
                polygon: {
                  hierarchy: polygonHierarchy,
                  material: Cesium.Color.fromCssColorString(
                    'rgba(49,120,252,0.5)'
                  ),
                  outline: true,
                  outlineColor: Cesium.Color.BLACK,
                },
              })

              // 存储到矩形列表中
              const polygonObj = {
                name: 'measurePolygon',
                entity: polygonEntity,
              }
              measurePolygonList[measurePolygonList.length - 1].push(polygonObj)
            }

            // 将点实体添加到集合中
            const pointEntity = viewer.entities.add({
              name: 'measurePoint',
              position: earthPosition,
              point: {
                pixelSize: 5, //点的大小
                color: Cesium.Color.WHITE, //点的颜色
                outlineColor: Cesium.Color.fromCssColorString(
                  'rgba(49,120,252,0.8)'
                ), //外圈颜色
                outlineWidth: 2, //外圈大小
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
              },
            })

            // 存储到矩形列表中
            const pointObj = {
              name: 'measurePoint',
              entity: pointEntity,
            }
            measurePolygonList[measurePolygonList.length - 1].push(pointObj)
          }
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

    // 添加鼠标移动功能 —— 鼠标移动过程中查看多边形区域
    measurePolygonEventHander.setInputAction((movement) => {
      const newPosition = viewer.scene.pickPosition(movement.endPosition)

      if (Cesium.defined(newPosition)) {
        if (clickPoint.length === 1) {
          const movePoint = [...clickPoint, newPosition]

          removePolygonEntityByName(viewer, 'moveMeasurePolygon')
          const movePolylineEntity = viewer.entities.add({
            name: 'moveMeasurePolygon',
            polyline: {
              positions: new Cesium.CallbackProperty(function () {
                return movePoint
              }, false),
              material: new Cesium.PolylineDashMaterialProperty({
                color: Cesium.Color.fromCssColorString('rgba(49,120,252,0.8)'),
                dashLength: 10, //短划线长度
              }),
              width: 2.0,
              clampToGround: true,
            },
          })

          // 存储到矩形列表中
          const polylineObj = {
            name: 'moveMeasurePolygon',
            entity: movePolylineEntity,
          }
          measurePolygonList[measurePolygonList.length - 1].push(polylineObj)
        } else if (clickPoint.length > 1) {
          const movePoint = [...clickPoint, newPosition]

          removePolygonEntityByName(viewer, 'moveMeasurePolygon')
          const movePolygonEntity = viewer.entities.add({
            name: 'moveMeasurePolygon',
            polygon: {
              hierarchy: new Cesium.CallbackProperty(function () {
                const obj = new Cesium.PolygonHierarchy(movePoint)
                return obj
              }, false),
              material: Cesium.Color.fromCssColorString(
                'rgba(120,167,255,0.48)'
              ),
              outline: true,
              outlineColor: Cesium.Color.BLACK,
            },
          })
          // 存储到矩形列表中
          const polygonObj = {
            name: 'moveMeasurePolygon',
            entity: movePolygonEntity,
          }
          measurePolygonList[measurePolygonList.length - 1].push(polygonObj)
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)

    // 添加鼠标右键点击功能 —— 撤销多边形上一点
    measurePolygonEventHander.setInputAction(() => {
      removePolygonEntityByName(viewer, 'measurePolygon')
      removePolygonEntityByName(viewer, 'moveMeasurePolygon')
      clickPoint.pop()
      verdictPoint.pop()
      const subListLength =
        measurePolygonList[measurePolygonList.length - 1].length

      if (subListLength > 0) {
        const isRemove = viewer.entities.remove(
          measurePolygonList[measurePolygonList.length - 1][subListLength - 1]
            .entity
        )
        if (isRemove) {
          // 数组中移除数据
          measurePolygonList[measurePolygonList.length - 1].pop()
        }
      }

      const polygonHierarchy = new Cesium.PolygonHierarchy(clickPoint)
      // 将实体添加到集合中
      const polygonEntity = viewer.entities.add({
        name: 'measurePolygon',
        polygon: {
          hierarchy: polygonHierarchy,
          material: Cesium.Color.fromCssColorString('rgba(49,120,252,0.5)'),
          outline: true,
          outlineColor: Cesium.Color.BLACK,
        },
      })

      // 存储到矩形列表中
      const polygonObj = {
        name: 'measurePolygon',
        entity: polygonEntity,
      }
      measurePolygonList[measurePolygonList.length - 1].push(polygonObj)
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)

    // 添加鼠标双击左键点击功能 —— 绘制完成测量面积
    measurePolygonEventHander.setInputAction(() => {
      if (clickPoint.length > 2) {
        const objItem = measurePolygonList[measurePolygonList.length - 1].find(
          (item) => item.name === 'measurePolygon'
        )

        const polygonArea = calculatedTotalArea(viewer, clickPoint) //面积
        clickPoint.push(clickPoint[0])
        const polygonPerimeter = calculatedTotalDistance(clickPoint) //周长

        const polygonPositions = objItem.entity.polygon.hierarchy.getValue(
          Cesium.JulianDate.now()
        ).positions
        var centerPolygon =
          Cesium.BoundingSphere.fromPoints(polygonPositions).center

        // 将文字实体添加到集合中
        const labelEntity = viewer.entities.add({
          name: 'measureLabel',
          position: centerPolygon,
          label: {
            text: `周长: ${
              polygonPerimeter.toFixed(2) > 1000
                ? (polygonPerimeter / 1000).toFixed(2) + '千米'
                : polygonPerimeter.toFixed(2) + '米'
            } \n 面积: ${
              polygonArea.toFixed(4) > 1000000
                ? (polygonArea / 1000000).toFixed(4) + '平方公里'
                : polygonArea.toFixed(4) + '平方米'
            }`,
            font: '16px sans-serif',
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            fillColor: Cesium.Color.WHITE,
            outlineColor: Cesium.Color.WHITE,
            showBackground: true, //指定标签后面背景的可见性
            backgroundColor: Cesium.Color.fromCssColorString('rgba(0,0,0,0.6)'), // 背景颜色
            backgroundPadding: new Cesium.Cartesian2(6, 12), //指定以像素为单位的水平和垂直背景填充padding
            scaleByDistance: new Cesium.NearFarScalar(2000, 1, 80000, 0.5),
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
              0,
              80000
            ),
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          },
        })

        // 存储到矩形列表中
        const labelObj = {
          name: 'measureLabel',
          entity: labelEntity,
        }
        measurePolygonList[measurePolygonList.length - 1].push(labelObj)

        clickPoint = [] // 清空
        verdictPoint = [] // 清空

        measurePolygonList.push([])
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
  }
}

/** 移除测量面积Entity
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 * @param {string} entityName 移除的entity名称
 */
const removePolygonEntityByName = (viewer, entityName) => {
  // 获取移除数据在 entitieList中的位置
  const objItem = measurePolygonList[measurePolygonList.length - 1].find(
    (item) => item.name === entityName
  )
  const objIndex =
    measurePolygonList[measurePolygonList.length - 1].indexOf(objItem)

  // 移除图层数据
  if (objItem) {
    const isRemove = viewer.entities.remove(objItem.entity)
    if (isRemove) {
      // 数组中移除数据
      measurePolygonList[measurePolygonList.length - 1].splice(objIndex, 1)
    }
  }
}

/** 计算多边形面积
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 * @param {Array<Cartesian3>} Cartesian3Ponit 点集合
 */
const calculatedTotalArea = (viewer, Cartesian3Ponit) => {
  const ellipsoid = viewer.scene.globe.ellipsoid
  // 将Cartesian3Ponit里的数据转为经纬度
  const pointArray = Cartesian3Ponit.map((item) => {
    //将笛卡尔坐标转换为地理坐标
    const cartographic = ellipsoid.cartesianToCartographic(item)
    //将弧度转为度的十进制度表示
    const lng = Cesium.Math.toDegrees(cartographic.longitude)
    const lat = Cesium.Math.toDegrees(cartographic.latitude)
    return [lng, lat]
  })
  pointArray.push(pointArray[0])

  const turfPolygon = turf.polygon([pointArray])
  const polygonArea = turf.area(turfPolygon)

  return polygonArea
}

// 定义是否开启三角量测功能
let ismeasureTriangle = true
// 定义三角量测数据列表
let measureTriangleList = [[]]
// 定义三角量测的输入事件
let measureTriangleEventHander = null

/** 三角量测
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 */
export const measureTriangle = (viewer) => {
  if (ismeasureTriangle) {
    // 防止二次定义
    ismeasureTriangle = false

    // 定义三角量测的输入事件
    measureTriangleEventHander = new Cesium.ScreenSpaceEventHandler(
      viewer.scene.canvas
    )
    // 定义点击点的集合
    let clickPoint = []

    // 添加鼠标左键点击功能 —— 三角量测
    measureTriangleEventHander.setInputAction((movement) => {
      const earthPosition = viewer.scene.pickPosition(movement.position)
      if (Cesium.defined(earthPosition)) {
        // 判断现在是第几个点
        if (clickPoint.length === 0) {
          //还没有点，添加第一个点
          clickPoint.push(earthPosition)

          // 将点实体添加到集合中
          const pointEntity = viewer.entities.add({
            name: 'measurePoint',
            position: earthPosition,
            point: {
              pixelSize: 5, //点的大小
              color: Cesium.Color.WHITE, //点的颜色
              outlineColor: Cesium.Color.fromCssColorString(
                'rgba(49,120,252,0.8)'
              ), //外圈颜色
              outlineWidth: 2, //外圈大小
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
            },
          })

          // 存储到矩形列表中
          const pointObj = {
            name: 'measurePoint',
            entity: pointEntity,
          }
          measureTriangleList[measureTriangleList.length - 1].push(pointObj)
        } else {
          // 一处移动绘制的虚线
          removeTriangleEntityByName(viewer, 'measurePoint')
          removeTriangleEntityByName(viewer, 'moveMeasureTriangle')

          clickPoint.push(earthPosition)

          const cartographic1 = Cesium.Cartographic.fromCartesian(clickPoint[0])
          const lon1 = Cesium.Math.toDegrees(cartographic1.longitude)
          const lat1 = Cesium.Math.toDegrees(cartographic1.latitude)
          const height1 = cartographic1.height

          const cartographic2 = Cesium.Cartographic.fromCartesian(clickPoint[1])
          const lon2 = Cesium.Math.toDegrees(cartographic2.longitude)
          const lat2 = Cesium.Math.toDegrees(cartographic2.latitude)
          const height2 = cartographic2.height //模型高度

          const triangleEntity = viewer.entities.add({
            name: 'measureTriangle',
            polyline: {
              positions:
                height2 > height1
                  ? new Cesium.Cartesian3.fromDegreesArrayHeights([
                      lon1,
                      lat1,
                      height1,
                      lon1,
                      lat1,
                      height2,
                      lon2,
                      lat2,
                      height2,
                      lon1,
                      lat1,
                      height1,
                    ])
                  : new Cesium.Cartesian3.fromDegreesArrayHeights([
                      lon1,
                      lat1,
                      height1,
                      lon2,
                      lat2,
                      height2,
                      lon2,
                      lat2,
                      height1,
                      lon1,
                      lat1,
                      height1,
                    ]),
              arcType: Cesium.ArcType.NONE,
              width: 2,
              material: Cesium.Color.fromCssColorString('rgba(49,120,252,0.8)'),
              depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty({
                color: Cesium.Color.RED,
              }),
            },
          })

          // 存储到矩形列表中
          const triangleObj = {
            name: 'measureTriangle',
            entity: triangleEntity,
          }
          measureTriangleList[measureTriangleList.length - 1].push(triangleObj)

          // 空间
          let triangleDistance = Cesium.Cartesian3.distance(
            Cesium.Cartesian3.fromDegrees(lon1, lat1),
            Cesium.Cartesian3.fromDegrees(lon2, lat2)
          )
          //高度
          let triangleHeight = Math.abs(height1 - height2)
          //直线距离
          let triangleLineDistance = Math.sqrt(
            Math.pow(triangleDistance, 2) + Math.pow(triangleHeight, 2)
          )

          const labelEntityA = viewer.entities.add({
            name: 'measureLabelA',
            position: Cesium.Cartesian3.fromDegrees(
              (lon1 + lon2) / 2,
              (lat1 + lat2) / 2,
              Math.max(height1, height2)
            ),
            label: {
              text: `空间距离:${
                triangleDistance.toFixed(2) > 1000
                  ? (triangleDistance / 1000).toFixed(2) + 'KM'
                  : triangleDistance.toFixed(2) + 'M'
              }`,
              translucencyByDistance: new Cesium.NearFarScalar(
                1.5e2,
                2.0,
                1.5e5,
                0
              ),
              font: '14px 楷体',
              style: Cesium.LabelStyle.FILL_AND_OUTLINE,
              fillColor: Cesium.Color.WHITE,
              outlineColor: Cesium.Color.WHITE,
              showBackground: true, //指定标签后面背景的可见性
              backgroundColor:
                Cesium.Color.fromCssColorString('rgba(0,0,0,0.6)'), // 背景颜色
              backgroundPadding: new Cesium.Cartesian2(6, 6), //指定以像素为单位的水平和垂直背景填充padding
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
              pixelOffset: new Cesium.Cartesian2(0, -10),
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            },
          })
          // 存储到矩形列表中
          const labelObjA = {
            name: 'measureLabelA',
            entity: labelEntityA,
          }
          measureTriangleList[measureTriangleList.length - 1].push(labelObjA)

          const labelEntityB = viewer.entities.add({
            name: 'measureLabelB',
            position:
              height2 > height1
                ? Cesium.Cartesian3.fromDegrees(
                    lon1,
                    lat1,
                    (height1 + height2) / 2
                  )
                : Cesium.Cartesian3.fromDegrees(
                    lon2,
                    lat2,
                    (height1 + height2) / 2
                  ),
            label: {
              text: `高度差:${
                triangleHeight.toFixed(2) > 1000
                  ? (triangleHeight / 1000).toFixed(2) + 'KM'
                  : triangleHeight.toFixed(2) + 'M'
              }`,
              translucencyByDistance: new Cesium.NearFarScalar(
                1.5e2,
                2.0,
                1.5e5,
                0
              ),
              font: '14px 楷体',
              style: Cesium.LabelStyle.FILL_AND_OUTLINE,
              fillColor: Cesium.Color.WHITE,
              outlineColor: Cesium.Color.WHITE,
              showBackground: true, //指定标签后面背景的可见性
              backgroundColor:
                Cesium.Color.fromCssColorString('rgba(0,0,0,0.6)'), // 背景颜色
              backgroundPadding: new Cesium.Cartesian2(6, 6), //指定以像素为单位的水平和垂直背景填充padding
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            },
          })
          // 存储到矩形列表中
          const labelObjB = {
            name: 'measureLabelB',
            entity: labelEntityB,
          }
          measureTriangleList[measureTriangleList.length - 1].push(labelObjB)

          const labelEntityC = viewer.entities.add({
            name: 'measureLabelC',
            position: Cesium.Cartesian3.fromDegrees(
              (lon1 + lon2) / 2,
              (lat1 + lat2) / 2,
              (height1 + height2) / 2
            ),
            label: {
              text: `直线距离:${
                triangleLineDistance.toFixed(2) > 1000
                  ? (triangleLineDistance / 1000).toFixed(2) + 'KM'
                  : triangleLineDistance.toFixed(2) + 'M'
              }`,
              translucencyByDistance: new Cesium.NearFarScalar(
                1.5e2,
                2.0,
                1.5e5,
                0
              ),
              font: '14px 楷体',
              style: Cesium.LabelStyle.FILL_AND_OUTLINE,
              fillColor: Cesium.Color.WHITE,
              outlineColor: Cesium.Color.WHITE,
              showBackground: true, //指定标签后面背景的可见性
              backgroundColor:
                Cesium.Color.fromCssColorString('rgba(0,0,0,0.6)'), // 背景颜色
              backgroundPadding: new Cesium.Cartesian2(6, 6), //指定以像素为单位的水平和垂直背景填充padding
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            },
          })
          // 存储到矩形列表中
          const labelObjC = {
            name: 'measureLabelC',
            entity: labelEntityC,
          }
          measureTriangleList[measureTriangleList.length - 1].push(labelObjC)

          clickPoint = [] // 清空
          measureTriangleList.push([])
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

    // 添加鼠标移动功能 —— 鼠标移动过程中查看多边形区域
    measureTriangleEventHander.setInputAction((movement) => {
      const newPosition = viewer.scene.pickPosition(movement.endPosition)

      if (Cesium.defined(newPosition)) {
        if (clickPoint.length > 0) {
          const movePoint = [clickPoint[0], newPosition]

          removeTriangleEntityByName(viewer, 'moveMeasureTriangle')
          // 将实体添加到集合中
          const moveTriangleEntity = viewer.entities.add({
            name: 'moveMeasureTriangle',
            polyline: {
              positions: new Cesium.CallbackProperty(function () {
                return movePoint
              }, false),
              material: new Cesium.PolylineDashMaterialProperty({
                color: Cesium.Color.fromCssColorString('rgba(49,120,252,0.8)'),
                dashLength: 10, //短划线长度
              }),
              width: 2.0,
              clampToGround: true,
            },
          })

          // 存储到矩形列表中
          const polylineObj = {
            name: 'moveMeasureTriangle',
            entity: moveTriangleEntity,
          }
          measureTriangleList[measureTriangleList.length - 1].push(polylineObj)
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }
}

/** 移除三角量测Entity
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 * @param {string} entityName 移除的entity名称
 */
const removeTriangleEntityByName = (viewer, entityName) => {
  // 获取移除数据在 entitieList中的位置
  const objItem = measureTriangleList[measureTriangleList.length - 1].find(
    (item) => item.name === entityName
  )
  const objIndex =
    measureTriangleList[measureTriangleList.length - 1].indexOf(objItem)

  // 移除图层数据
  if (objItem) {
    const isRemove = viewer.entities.remove(objItem.entity)
    if (isRemove) {
      // 数组中移除数据
      measureTriangleList[measureTriangleList.length - 1].splice(objIndex, 1)
    }
  }
}

/** 移除距离测量事件 */
export const removePolylineEventHander = () => {
  if (measurePolylineEventHander) {
    measurePolylineEventHander.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_CLICK
    ) //停止监听鼠标左键点击事件
    measurePolylineEventHander.removeInputAction(
      Cesium.ScreenSpaceEventType.MOUSE_MOVE
    ) //停止监听移动事件
    measurePolylineEventHander.removeInputAction(
      Cesium.ScreenSpaceEventType.RIGHT_CLICK
    ) //停止监听鼠标右键点击事件
    measurePolylineEventHander.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    ) //停止监听鼠标双击左键点击事件

    measurePolylineEventHander = null
    ismeasurePolyline = true
  }
}

/** 清除距离测量
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 */
export const clearMeasurePolyline = (viewer) => {
  measurePolylineList.forEach((item) => {
    item.forEach((subItem) => {
      viewer.entities.remove(subItem.entity)
    })
  })

  measurePolylineList = [[]]
}

/** 移除面积测量事件 */
export const removePolygonEventHander = () => {
  if (measurePolygonEventHander) {
    measurePolygonEventHander.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_CLICK
    ) //停止监听鼠标左键点击事件
    measurePolygonEventHander.removeInputAction(
      Cesium.ScreenSpaceEventType.MOUSE_MOVE
    ) //停止监听移动事件
    measurePolygonEventHander.removeInputAction(
      Cesium.ScreenSpaceEventType.RIGHT_CLICK
    ) //停止监听鼠标右键点击事件
    measurePolygonEventHander.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    ) //停止监听鼠标双击左键点击事件

    measurePolygonEventHander = null
    ismeasurePolygon = true
  }
}

/** 清除面积测量
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 */
export const clearMeasurePolygon = (viewer) => {
  measurePolygonList.forEach((item) => {
    item.forEach((subItem) => {
      viewer.entities.remove(subItem.entity)
    })
  })

  measurePolygonList = [[]]
}

/** 移除三角量测事件 */
export const removeTriangleEventHander = () => {
  if (measureTriangleEventHander) {
    measureTriangleEventHander.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_CLICK
    ) //停止监听鼠标左键点击事件
    measureTriangleEventHander.removeInputAction(
      Cesium.ScreenSpaceEventType.MOUSE_MOVE
    ) //停止监听移动事件

    measureTriangleEventHander = null
    ismeasureTriangle = true
  }
}
/** 清除三角量测
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 */
export const clearMeasureTriangle = (viewer) => {
  measureTriangleList.forEach((item) => {
    item.forEach((subItem) => {
      viewer.entities.remove(subItem.entity)
    })
  })

  measureTriangleList = [[]]
}

/** 清除全部
 * @param {Cesium.Viewer} viewer Cesium三维视窗
 */
export const clearMeasureAll = (viewer) => {
  clearMeasurePolyline(viewer)
  clearMeasurePolygon(viewer)
  clearMeasureTriangle(viewer)
}
